# Vue JSX 插件

import { SourceCode } from 'rspress/theme';

<SourceCode href="https://github.com/web-infra-dev/rsbuild/tree/main/packages/plugin-vue-jsx" />

Vue JSX 插件提供了对 Vue 3 JSX / TSX 语法的支持，插件内部集成了 [@vue/babel-plugin-jsx](https://github.com/vuejs/babel-plugin-jsx)。

## 快速开始

### 安装插件

你可以通过如下的命令安装插件:

import { PackageManagerTabs } from '@theme';

<PackageManagerTabs command="add @rsbuild/plugin-babel @rsbuild/plugin-vue-jsx -D" />

### 注册插件

你可以在 `rsbuild.config.ts` 文件中注册插件：

```ts title="rsbuild.config.ts"
import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';

export default {
  plugins: [
    pluginBabel({
      include: /\.(?:jsx|tsx)$/,
      exclude: /[\\/]node_modules[\\/]/,
    }),
    pluginVueJsx(),
  ],
};
```

注册插件后，你可以在 `.jsx`、`.tsx` 和 `.vue` 文件中使用 Vue 的 [JSX / TSX 语法](https://github.com/vuejs/babel-plugin-jsx)。

:::tip
由于 Vue 的 JSX 插件依赖 Babel 进行编译，因此你需要额外添加 [Babel 插件](/plugins/list/plugin-babel)。

Babel 编译会产生额外的编译开销，在上述例子中，我们通过 `include` 来匹配 `.jsx` 和 `.tsx` 文件，从而减少 Babel 带来的性能开销。

:::

## Vue SFC

在 Vue SFC 中使用 JSX 时，你需要在 `<script>` 标签上添加 `lang="jsx"` 或 `lang="tsx`"。

- JSX：

```html title="App.vue"
<script lang="jsx">
  const vnode = <div>hello</div>;
</script>
```

- TSX：

```html title="App.vue"
<script lang="tsx">
  const vnode = <div>hello</div>;
</script>
```

## JSX 类型推导

在使用 Vue >= 3.3 版本时，请在 `tsconfig.json` 中设置 `"jsxImportSource": "vue"`，以启用 JSX 类型推导。

```json title="tsconfig.json"
{
  "compilerOptions": {
    "jsxImportSource": "vue"
  }
}
```

详见 [Vue - JSX Type Inference](https://vuejs.org/guide/extras/render-function.html#jsx-type-inference)。

## 选项

如果你需要自定义 Vue 的编译行为，可以使用以下配置项。

### vueJsxOptions

传递给 `@vue/babel-plugin-jsx` 的选项，请查阅 [@vue/babel-plugin-jsx 文档](https://github.com/vuejs/babel-plugin-jsx) 来了解具体用法。

- **类型：**

```ts
type VueJSXPluginOptions = {
  /** 将 `on: { click: someCallback }` 转换为 `onClick: someCallback` */
  transformOn?: boolean;
  /** 是否启用优化。 */
  optimize?: boolean;
  /** 合并静态和动态 class / style 属性 / onSomething 事件处理函数 */
  mergeProps?: boolean;
  /** 配置自定义元素 */
  isCustomElement?: (tag: string) => boolean;
  /** 启用对象插槽语法 */
  enableObjectSlots?: boolean;
  /** 替换用于编译 JSX 表达式的函数 */
  pragma?: string;
};
```

- **默认值：** `{}`

- **示例：**

```ts
pluginVueJsx({
  vueJsxOptions: {
    transformOn: true,
  },
});
```
